package com.unlcn.ils.crsc.service.ftp.util;


import com.google.common.collect.Lists;
import com.unlcn.ils.crsc.service.ftp.config.FtpConfig;
import com.unlcn.ils.crsc.service.util.BaseException;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPFileFilter;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.SocketException;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

@Component
public class FtpUtil {

    //静态注入的方式
    private static FtpConfig ftpConfig;

    @Autowired
    public void setFtpConfig(FtpConfig ftpConfig) {
        FtpUtil.ftpConfig = ftpConfig;
    }

    private static final Logger logger = LoggerFactory.getLogger(FtpUtil.class);

    /**
     * 获取FTPClient对象
     *
     * @return
     */
    private static FTPClient getFTPClient() {
        FTPClient ftpClient = null;
        try {
            ftpClient = new FTPClient();
            ftpClient.connect(ftpConfig.getFtpUrl(), ftpConfig.getFtpPort());// 连接FTP服务器
            ftpClient.login(ftpConfig.getUsername(), ftpConfig.getPassword());// 登陆FTP服务器
            if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                logger.info("未连接到FTP，用户名或密码错误。");
                ftpClient.disconnect();
            } else {
                logger.info("FTP连接成功。");
            }
        } catch (SocketException e) {
            e.printStackTrace();
            logger.info("FTP的IP地址可能错误，请正确配置。");
        } catch (IOException e) {
            e.printStackTrace();
            logger.info("FTP的端口错误,请正确配置。");
        }
        return ftpClient;
    }


    /**
     * 得到路径下的所有文件名
     *
     * @param pathName
     * @return
     * @throws IOException
     */
    public static List<String> listFiles(String pathName) throws IOException {
        FTPClient ftpClient = null;
        List<String> arFiles = Lists.newArrayList();
        try {
            ftpClient = getFTPClient();
            if (pathName.startsWith("/") && pathName.endsWith("/")) {
                String directory = pathName;
                //更换目录到当前目录
                ftpClient.changeWorkingDirectory(directory);
                FTPFile[] files = ftpClient.listFiles();
                for (FTPFile file : files) {
                    if (file.isFile()) {
                        arFiles.add(file.getName());
                    } else if (file.isDirectory()) {
                        listFiles(directory + file.getName() + "/");
                    }
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
            throw new BaseException(e.getMessage());
        } finally {
            if (!Objects.isNull(ftpClient)) {
                ftpClient.disconnect();
            }
        }
        return arFiles;
    }

    /**
     * 得到路径下的所有文件名
     * @param pathName
     * @param filterName
     * @return
     * @throws IOException
     */
    public static List<String> listFiles(String pathName,String filterName) throws IOException {
        FTPClient ftpClient = null;
        List<String> arFiles = Lists.newArrayList();
        try {
            ftpClient = getFTPClient();
            if (pathName.startsWith("/") && pathName.endsWith("/")) {
                String directory = pathName;
                //更换目录到当前目录
                ftpClient.changeWorkingDirectory(directory);
                FTPFile[] files = ftpClient.listFiles(pathName, new FTPFileFilter() {
                    @Override
                    public boolean accept(FTPFile ftpFile) {
                        return ftpFile.getName().contains(filterName);
                    }
                });
                if(!ArrayUtils.isEmpty(files)){
                    Arrays.asList(files).forEach(ftpFile -> {
                        arFiles.add(ftpFile.getName());
                    });
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
            throw new BaseException(e.getMessage());
        } finally {
            if (!Objects.isNull(ftpClient)) {
                ftpClient.disconnect();
            }
        }
        return arFiles;
    }

    /**
     * 得到路径下的所有文件
     *
     * @param pathName
     * @return
     * @throws IOException
     */
    public static List<FTPFile> listFTPFiles(String pathName) throws IOException {
        FTPClient ftpClient = null;
        List<FTPFile> arFiles = Lists.newArrayList();
        try {
            ftpClient = getFTPClient();
            if (pathName.startsWith("/") && pathName.endsWith("/")) {
                String directory = pathName;
                //更换目录到当前目录
                ftpClient.changeWorkingDirectory(directory);
                FTPFile[] files = ftpClient.listFiles();
                arFiles = Arrays.asList(files);
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
            throw new BaseException(e.getMessage());
        } finally {
            if (!Objects.isNull(ftpClient)) {
                ftpClient.disconnect();
            }

        }
        return arFiles;
    }


    /**
     * 下载文件
     *
     * @param ftpFile
     * @param relativeLocalPath 下载的目的地
     */
    public static void downloadFile(FTPFile ftpFile, String relativeLocalPath) {
        FTPClient ftpClient = null;
        if (ftpFile.isFile()) {
            if (ftpFile.getName().indexOf("?") == -1) {
                OutputStream outputStream = null;
                try {
                    ftpClient = getFTPClient();
                    File entryDir = new File(relativeLocalPath);
                    //如果文件夹路径不存在，则创建文件夹
                    if (!entryDir.exists() || !entryDir.isDirectory()) {
                        entryDir.mkdirs();
                    }
                    File locaFile = new File(relativeLocalPath + ftpFile.getName());
                    //判断文件是否存在，存在则返回
                    if (locaFile.exists()) {
                        return;
                    } else {
                        outputStream = new FileOutputStream(relativeLocalPath + ftpFile.getName());
                        ftpClient.retrieveFile(ftpFile.getName(), outputStream);
                        outputStream.flush();
                        outputStream.close();
                    }
                } catch (Exception e) {
                    logger.error(e.getMessage());
                } finally {
                    try {
                        if (outputStream != null) {
                            outputStream.close();
                        }
                        if (!Objects.isNull(ftpClient)) {
                            logger.info("连接关闭");
                            ftpClient.disconnect();
                        }
                    } catch (IOException e) {
                        logger.error("输出文件流异常");
                    }
                }
            }
        }
    }


    /**
     * 下载单个文件
     * @param fileName
     * @param relativeLocalPath
     */
    public static void downloadFile(String fileName, String relativeLocalPath) {
        FTPClient ftpClient = null;
        if (fileName.indexOf("?") == -1) {
            OutputStream outputStream1 = null;
            try {
                ftpClient = getFTPClient();
                File entryDir = new File(relativeLocalPath);
                //如果文件夹路径不存在，则创建文件夹
                if (!entryDir.exists() || !entryDir.isDirectory()) {
                    entryDir.mkdirs();
                }
                File locaFile = new File(relativeLocalPath + fileName);
                //判断文件是否存在，存在则返回
                if (locaFile.exists()) {
                    return;
                } else {
                    outputStream1 = new FileOutputStream(relativeLocalPath + fileName);
                    ftpClient.retrieveFile(fileName, outputStream1);
                    outputStream1.flush();
                    outputStream1.close();
                }
            } catch (Exception e) {
                logger.error(e.getMessage());
            } finally {
                try {
                    if (outputStream1 != null) {
                        outputStream1.close();
                    }
                    if (!Objects.isNull(ftpClient)) {
                        logger.info("FTP连接关闭");
                        ftpClient.disconnect();
                    }
                } catch (IOException e) {
                    logger.error("输出文件流异常");
                }
            }
        }
    }

    /**
     * 删除文件夹下的文件
     *
     * @param pathName 路径名
     * @param fileName 文件名
     * @return
     * @throws IOException
     */
    public static Boolean DeleteFile(String pathName, String fileName) throws IOException {
        Boolean blnRtn = false;
        FTPClient ftpClient = null;
        try {
            ftpClient = getFTPClient();
            FTPFile[] ftpFiles = ftpClient.listFiles(pathName, new FTPFileFilter() {
                @Override
                public boolean accept(FTPFile ftpFile) {
                    return ftpFile.getName().equals(fileName);
                }
            });
            if (!ArrayUtils.isEmpty(ftpFiles)) {
                String path = pathName + fileName;
                blnRtn = ftpClient.deleteFile(path);
            } else {
                blnRtn = true;
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
            throw new BaseException(e.getMessage());
        } finally {
            if (!Objects.isNull(ftpClient)) {
                ftpClient.disconnect();
            }

        }
        return blnRtn;
    }

}
